# -*- coding: utf-8 -*-
import unittest
import sys
import os
import time

# 添加执行环境
file_exec_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
sys.path.insert(0, file_exec_path)
from framework_strategy.gopy.trader.engine import EmailEngine, MainEngine, EventEngine  # NOQA
from framework_strategy.gopy.base.api import API, Event  # NOQA
from framework_strategy.gopy.gateways.object import *  # NOQA
from framework_strategy.gopy.gateways.binance.binance_api import BINANCEGateway  # NOQA


def init_engine():
    event_engine = EventEngine()
    main_engine = MainEngine(event_engine)
    xt_gateway = BINANCEGateway(main_engine, event_engine, "BINANCE")
    # event_engine.start()
    # 获取服务器时间同步获取
    api = API(event_engine)
    return event_engine, api


class TestBinanceGateway(unittest.TestCase):

    @unittest.skip
    def test_gateway_init(self):
        # TODO: 'ServerTimeData' object has no attribute 'event_data'
        event_engine = EventEngine()
        main_engine = MainEngine(event_engine)
        xgw = BINANCEGateway(main_engine, event_engine, "BINANCE")
        print("++++++++++++++++++++++++++", vars(xgw))
        xgw.on_bind()

    @unittest.skip
    def test_on_event_active(self):
        '''
        binance 
            {'serverTime': 1656580553792,}
        '''
        """ 测试事件获取是否有效 """

        event_engine = EventEngine()
        main_engine = MainEngine(event_engine)
        xt_gateway = BINANCEGateway(main_engine, event_engine, "BINANCE")
        # event_engine.start()
        # 获取服务器时间同步获取
        api = API(event_engine)
        server_time_event = ServerTimeData(_source="BINANCE")
        print(vars(server_time_event))
        # 使用驱动调用
        nt = time.time()
        api.get_server_time(server_time_event)
        # # 调用驱动来获取同步数据
        # print(time.time() - nt)
        res = server_time_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()

    @unittest.skip
    def test_on_event_get_market_config(self):
        event_engine, api = init_engine()
        market_event = MarketsConfigData(_source="BINANCE")
        nt = time.time()
        api.get_all_market_config(market_event)
        res = market_event.get_result(timeout=5)
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()

    @unittest.skip
    def test_on_event_get_market_kline(self):
        '''
        binance
            [[1656641040000, '20382.72000000', '20384.08000000', '20372.45000000', '20372.45000000', '19.89693000', 1656641099999, '405461.72693610', 309, '8.96439000', '182657.67525860', '0']]            
        '''
        # TODO: 参数值不一致
        event_engine, api = init_engine()
        market_event = MarketKlineData(_source="BINANCE", market="btc_usdt", type="1m", since=int(time.time()))
        nt = time.time()
        api.get_klines(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        # print(res.response.content, res.response.url)
        event_engine.stop()

    @unittest.skip
    def test_on_event_get_market_ticker(self):
        '''
        binance
            [{'symbol': 'WBTCBUSD', 'price': '20392.56000000'}]
        '''
        event_engine, api = init_engine()
        market_event = MarketTickerData(_source="BINANCE", market="btc_usdt")
        nt = time.time()
        api.get_tickers(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()
        pass

    @unittest.skip
    def test_on_event_get_market_tickers(self):
        '''
        binance
            [{'symbol': 'WBTCBUSD', 'price': '20392.56000000'}]
        '''
        event_engine, api = init_engine()
        market_event = MarketTickerData(_source="BINANCE")
        nt = time.time()
        api.get_tickers(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()
        pass

    @unittest.skip
    def test_on_event_get_market_depth(self):
        '''
        binance
            {'lastUpdateId': 20610487943, 'bids': [['20402.85000000', '2.20078000']], 
                'asks': [['20402.85000000', '2.20078000']]}
        '''
        event_engine, api = init_engine()
        market_event = MarketDepthData(_source="BINANCE", market="btc_usdt")
        nt = time.time()
        api.get_depth(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()

    # @unittest.skip
    def test_on_event_get_market_trades(self):
        '''
        xt
            接口未走通
        binance
            [{'id': 1431201333, 'price': '20450.35000000', 'qty': '0.00094000', 'quoteQty': '19.22332900', 
                'time': 1656641522907, 'isBuyerMaker': True, 'isBestMatch': True}]
        '''
        event_engine, api = init_engine()
        market_event = MarketTradesData(_source="BINANCE", market="btc_usdt")
        nt = time.time()
        api.get_trades(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt, res.response)
        event_engine.stop()

    @unittest.skip
    def test_on_event_get_balance(self):
        '''
        binance
            [{'asset': 'OP', 'free': '0.00000000', 'locked': '0.00000000'}]
        '''
        event_engine, api = init_engine()
        market_event = AccountBalanceData(_source="BINANCE")
        nt = time.time()
        api.get_balance(market_event)
        res = market_event.get_result()
        print("[*] res >>> ", res, time.time() - nt)
        event_engine.stop()

    @unittest.skip
    def test_on_event_get_open_order(self):
        '''
        binance
            [{
                "symbol": "LTCBTC",
                "orderId": 1,
                "orderListId": -1, // OCO订单ID，否则为 -1
                "clientOrderId": "myOrder1",
                "price": "0.1",
                "origQty": "1.0",
                "executedQty": "0.0",
                "cummulativeQuoteQty": "0.0",
                "status": "NEW",
                "timeInForce": "GTC",
                "type": "LIMIT",
                "side": "BUY",
                "stopPrice": "0.0",
                "icebergQty": "0.0",
                "time": 1499827319559,
                "updateTime": 1499827319559,
                "isWorking": true,
                "origQuoteOrderQty": "0.000000"
            }]
        '''
        event_engine, api = init_engine()
        market_event = AccountOpenOrderData(
            _source="BINANCE",
            market="btc_usdt",
        )
        nt = time.time()
        api.get_open_order(market_event)
        res = market_event.get_result()
        print("[*] AccountOpenOrderData >>> ", res, time.time() - nt)
        event_engine.stop()

    # TODO: not tested
    @unittest.skip
    def test_on_event_send_order(self):
        '''
        binance
        {
            "symbol": "BTCUSDT", // 交易对
            "orderId": 28, // 系统的订单ID
            "orderListId": -1, // OCO订单ID，否则为 -1
            "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", // 客户自己设置的ID
            "transactTime": 1507725176595, // 交易的时间戳
            "price": "0.00000000", // 订单价格
            "origQty": "10.00000000", // 用户设置的原始订单数量
            "executedQty": "10.00000000", // 交易的订单数量
            "cummulativeQuoteQty": "10.00000000", // 累计交易的金额
            "status": "FILLED", // 订单状态
            "timeInForce": "GTC", // 订单的时效方式
            "type": "MARKET", // 订单类型， 比如市价单，现价单等
            "side": "SELL", // 订单方向，买还是卖
            "fills": [ // 订单中交易的信息
                {
                "price": "4000.00000000", // 交易的价格
                "qty": "1.00000000", // 交易的数量
                "commission": "4.00000000", // 手续费金额
                "commissionAsset": "USDT", // 手续费的币种
                "tradeId": 56 // 交易ID
                },
                {
                "price": "3999.00000000",
                "qty": "5.00000000",
                "commission": "19.99500000",
                "commissionAsset": "USDT",
                "tradeId": 57
                },
                {
                "price": "3998.00000000",
                "qty": "2.00000000",
                "commission": "7.99600000",
                "commissionAsset": "USDT",
                "tradeId": 58
                },
                {
                "price": "3997.00000000",
                "qty": "1.00000000",
                "commission": "3.99700000",
                "commissionAsset": "USDT",
                "tradeId": 59
                },
                {
                "price": "3995.00000000",
                "qty": "1.00000000",
                "commission": "3.99500000",
                "commissionAsset": "USDT",
                "tradeId": 60
                }
            ]
        }
        '''
        event_engine, api = init_engine()
        market_event = AccountSendOrderData(
            _source="BINANCE",
            market="btc_usdt",
            price=18000,
            type=1,
            entrustType=0,
            number=0.001,
            #
        )
        nt = time.time()
        api.send_order(market_event)
        res = market_event.get_result()
        print("[*] AccountSendOrderData >>> ", res, time.time() - nt)
        event_engine.stop()
        # 6945670743361073152 订单撤销用
        pass

    @unittest.skip
    def test_on_event_cancel_order(self):
        '''
        binance
        {
            "symbol": "LTCBTC",
            "origClientOrderId": "myOrder1",
            "orderId": 4,
            "orderListId": -1, // OCO订单ID，否则为 -1
            "clientOrderId": "cancelMyOrder1",
            "price": "2.00000000",
            "origQty": "1.00000000",
            "executedQty": "0.00000000",
            "cummulativeQuoteQty": "0.00000000",
            "status": "CANCELED",
            "timeInForce": "GTC",
            "type": "LIMIT",
            "side": "BUY"
        }
        '''
        event_engine, api = init_engine()
        market_event = AccountCancelOrderData(
            _source="BINANCE",
            market="btc_usdt",
            id="6945670743361073152"
        )
        nt = time.time()
        api.cancel_order(market_event)
        res = market_event.get_result()
        print("[*] AccountCancelOrderData >>> ", res, time.time() - nt)
        event_engine.stop()
        pass

    @unittest.skip
    def test_on_event_get_order(self):
        '''
        binance
            {
                "symbol": "LTCBTC", // 交易对
                "orderId": 1, // 系统的订单ID
                "orderListId": -1, // OCO订单的ID，不然就是-1
                "clientOrderId": "myOrder1", // 客户自己设置的ID
                "price": "0.1", // 订单价格
                "origQty": "1.0", // 用户设置的原始订单数量
                "executedQty": "0.0", // 交易的订单数量
                "cummulativeQuoteQty": "0.0", // 累计交易的金额
                "status": "NEW", // 订单状态
                "timeInForce": "GTC", // 订单的时效方式
                "type": "LIMIT", // 订单类型， 比如市价单，现价单等
                "side": "BUY", // 订单方向，买还是卖
                "stopPrice": "0.0", // 止损价格
                "icebergQty": "0.0", // 冰山数量
                "time": 1499827319559, // 订单时间
                "updateTime": 1499827319559, // 最后更新时间
                "isWorking": true, // 订单是否出现在orderbook中
                "origQuoteOrderQty": "0.000000" // 原始的交易金额
            }
        '''
        event_engine, api = init_engine()
        market_event = AccountOrderData(
            _source="BINANCE",
            market="btc_usdt",
            id="6949650528546336768",)
        nt = time.time()
        api.get_order(market_event)
        res = market_event.get_result(timeout=2)
        print("[*] res >>> ", res, time.time() - nt, res.response)
        event_engine.stop()
        pass


if __name__ == "__main__":
    unittest.main()
